/*++

Copyright (c) 2007  Microsoft Corporation 

Filename: 

    Global.cs

Abstract: 

    Class that defines all Constants, Properties and Common Methods used
     
--*/
# region References
using System;
using System.Collections.Generic;
using System.Text;
using System.Resources;
using System.Reflection;
using Visio = Microsoft.Office.Interop.Visio;
using System.Collections;
using System.Windows.Forms;
using System.Security.Permissions;
using System.Globalization;

# endregion References

[assembly: SecurityPermission(SecurityAction.RequestMinimum, Execution = true)]
[assembly: System.CLSCompliant(false)]
namespace UtilityManager
{
    /// <summary>
    /// Class that defines all Constants, Properties and Common Methods used
    /// </summary>
    public sealed class Global
    {

        #region enum

        /// <summary>
        /// Enum for various options for diagram generation
        /// </summary>
        public enum InputDataOption
        {
            Wizard,
            Excel,
            Template
        }

        public enum DataOption
        {
            Wmi,
            Scom
        }

        /// <summary>
        /// Fill enums for ThreadState.
        /// </summary>
        public enum ThreadStop
        {
            Abort,
            Cancel,
            Complete
        }

        #endregion

        #region Member Variables

        private static ResourceManager resourceMgr = new ResourceManager("UtilityManager.GlobalResource", Assembly.GetExecutingAssembly());

        #region Addin Options
        private static int cpuUsageThreshold = 10;
        private static int maxServerConsolidate = 3;
        //private static int cpuUsageDuration = 1;
        //private static int cpuUsageDurationInHours = 1;

        #endregion

        private static string _NA = Global.GetResourceString("NotAvailable");


        private static string _CpuUsageThresholdProp = "CpuUsageThreshold";

        private static string _MaxServerConsolidateProp = "MaxServerConsolidate";

        private static string _ScomServerNameProp = "ScomServerName";

        private static string _ScomReportServerNameProp = "ScomReportServerName";

        private static string _WindowsAuthenticationProp = "WindowsAuthentication";

        private static string _UserCredentialsProp = "UserCredentials";

        private static string _DataOptionProp = "DataOption";

        private static string _ScomDatabaseNameProp = "ScomDatabaseName";

        private static string _ReportingDatabaseNameProp = "ReportingDatabaseName";

        private static string _UserNameProp = "UserName";

        #region Server table columns for virtualize
        public const string TableColServerId = "ServerRowID";
        public const string TableColServerName = "ServerRowName";
        public const string TableColPowerRating = "PowerRating";
        public const string TableColRackSpaceUsed = "RackSpaceUsed";
        public const string TableColCpuUsage = "CpuUsage";
        public const string TableColMemUsage = "MemUsage";
        public const string TableColIsVirtual = "IsVirtual";
        #endregion

        #region Visio Shape Properties
        // To identify type of the page, colo or rack.
        public const string PageTemplateProp = "PageType";
        public const string PageTemplateUserProp = "User." + PageTemplateProp;
        public const string PageTemplateUserPropValue = PageTemplateUserProp + ".Value";
        public const string PageTemplateColo = "Colo";
        public const string PageTemplateRack = "Rack";

        public const string DocTemplateUserProp = "User.IsServerVirtualization";

        
        public const string PropRackName = "Prop.RackName";
        public const string PropRackNameValue = "Prop.RackName.Value";

        public const string PropColoName = "Prop.ColoName";
        public const string PropColoNameValue = "Prop.ColoName.Value";

        public const string PropPowerRating = "Prop.PowerRating";
        public const string PropRackSpaceUsed = "Prop.RackSpaceUsed";
        public const string PropCpuUsage = "Prop.CPUUsage";
        public const string PropUCount = "Prop.UCount";
        public const string PropTotalMem = "Prop._VisDM_Total_Physical_Memory";
        public const string PropAvailMem = "Prop._VisDM_Available_Physical_Memory";
        public const string PropIsVirtual = "Prop._VisDM_Virtual_Server";

        public const string PropNetworkName = "Prop.NetworkName";

        public const string PropServerVirtualizable = "ServerVirtualizable";

        public const string RackVirtualizable = "RackVirtualizable";
        public const string PropRackVirtualizable = "User.RackVirtualizable";

        public const string VirtualRack = "VirtualRack";
        public const string UserVirtualRack = "User.VirtualRack";
        #endregion

        #region Visio documents
        private static string _RackServerTemplate = Global.AppPath() + "Template\\Rack Server Virtualization.vst";
        private static string _RackServerStencil = "RackSpace.vss";
        private static string _DefaultToolbar = Global.AppPath() + "Template\\DefaultToolbar.vsu";
        #endregion

        public const string ApplicationId = "RackServerAddin";
        public const string ApplicationIndex = "RackServerAddinIndex";

        #region Visio Shape Masters
        public const string ColoRackMasterName = "ColoRack";
        public const string TitleMasterName = "Border neon";
        public const string TitleBlockMasterName = "Title Block";
        public const string RackMasterName = "Rack";
        public const string ServerMasterName = "Server";
        public const string BraceMasterName = "Side brace";
        public const string SpaceBarMasterName = "45 Degree Double";
        public const string BalloonMasterName = "Balloon vertical";
        #endregion

        #region Context Strings
        public const string ApplicationContextString = "/app=";
        public const string DocumentContextString = "/doc=";
        public const string PageContextString = "/page=";
        public const string ShapeContextString = "/shape=";
        public const string ShapeUContextString = "/shapeU=";
        public const string CommandContextString = "/cmd=";
        #endregion

        #region Menu States
        public const string MenuStateDocumentOpen = "DocumentOpen";
        public const string MenuStateSetStatus = "SetStatusWindow";
        public const string MenuStateResetStatus = "ResetStatusWindow";
        public const string MenuStateToggleStatus = "ToggleStatus";
        #endregion

        #region Command Strings
        public const string CommandStringDrill = "DrillAction";
        public const string CommandStringConfigure = "Configure";
        public const string CommandStringImportData = "ImportData";
        public const string CommandStringAnalyze = "Analyze";
        public const string CommandStringVirtualize = "Virtualize";
        public const string CommandStringViewRackDetails = "ViewRackDetails";
        public const string CommandStringAnalyzeRack = "AnalyzeRack";
        public const string CommandStringVirtualizeRack = "VirtualizeRack";
        public const string CommandStringVirtualizeColo = "VirtualizeColo";
        public const string CommandStringRackVirtualize = "OnlyRack";
        public const string CommandStringRackAndServerVirtualize = "BothRackAndServer";
        public const string CommandStringShowStatusWindow = "StatusWindow";
        public const string CommandStringHelp = "Help";
        public const string CommandStringAbout = "About";
        #endregion

        #region Data Recordsets
        private static string _ColoDataRecordSetName = Global.GetResourceString("ColoDataRecordSetName");
        private static string _RackDataRecordSetName = Global.GetResourceString("RackDataRecordSetName");
        private static string _ServerDataRecordSetName = Global.GetResourceString("ServerDataRecordSetName");
        #endregion

        #region Server data record set columns
        private static string _ServerFieldNetworkName = Global.GetResourceString("ServerFieldNetworkName");
        private static string _ServerFieldPowerRating = Global.GetResourceString("ServerFieldPowerRating");
        private static string _ServerFieldRackSpace = Global.GetResourceString("ServerFieldRackSpace");
        private static string _ServerFieldRackName = Global.GetResourceString("ServerFieldRackName");
        private static string _ServerFieldColoName = Global.GetResourceString("ServerFieldColoName");
        private static string _ServerFieldIPAdress = Global.GetResourceString("ServerFieldIPAdress");
        private static string _ServerFieldOperatingSystem = Global.GetResourceString("ServerFieldOperatingSystem");
        private static string _ServerFieldCpuUsage = Global.GetResourceString("ServerFieldCPUUsage");
        private static string _ServerFieldTotalMem = Global.GetResourceString("ServerFieldTotalMem");
        private static string _ServerFieldAvailMem = Global.GetResourceString("ServerFieldAvailMem");
        private static string _ServerFieldProcessor = Global.GetResourceString("ServerFieldProcessor");
        private static string _ServerFieldIsVirtual = Global.GetResourceString("ServerFieldIsVirtual");

        #endregion

        #region Rack data record set columns
        private static string _RackFieldRackName = Global.GetResourceString("RackFieldRackName");
        private static string _RackFieldPowerRating = Global.GetResourceString("RackFieldPowerRating");
        private static string _RackFieldMaxUnits = Global.GetResourceString("RackFieldMaxUnits");
        private static string _RackFieldColoName = Global.GetResourceString("RackFieldColoName");
        #endregion

        #region Colo data record set columns
        private static string _ColoFieldColoName = Global.GetResourceString("ColoFieldColoName");
        private static string _ColoFieldMaxUnits = Global.GetResourceString("ColoFieldMaxUnits");
        #endregion

        #region Fields from WMI
        public const string WmiServerFieldIPAdress = "IPAddress";
        public const string WmiServerFieldOperatingSystem = "Caption";
        public const string WmiServerFieldCsdVersion = "CSDVersion";
        public const string WmiServerFieldCpuUsage = "PercentProcessorTime";//"LoadPercentage";
        public const string WmiServerFieldTotalMem = "TotalPhysicalMemory";
        public const string WmiServerFieldAvailMem = "FreePhysicalMemory";
        public const string WmiServerFieldProcessor = "Name";
        public const string WmiServerFieldManufacturer = "Manufacturer";
        #endregion

        private static string _excelFileName;
        private static InputDataOption _ipOption = InputDataOption.Excel;
        private static DataOption _dtOption = DataOption.Wmi;
        private static Visio.Application _visioApp;
        private static string[] _excelSheetsName;
        private static string[] _excelServerColumnName;
        private static string[] _excelRackColumnName;      
        private static string[] _excelColoColumnName;
        private static string _sheetServerSelect;
        private static string _sheetRackSelect;   
        private static string _sheetColoSelect;
        private static bool _recordSetCreated;

        private static bool _internalDocOpen;

        private static string _adoColoXML;
        private static string _adoRackXML;      
        private static string _adoServerXML;

        private static string _excelConnString;
        private static string _ServerSelectQuery;
        private static string _RackSelectQuery;
        private static string _ColoSelectQuery;
        private static string _userName;
        private static string _password;
        private static bool _userCredentials;
        private static bool _windowsAuthentication = true;

        private static bool _scomReportingServerAuthentication=true;


        #region Excel Worksheet Combobox Index
        private static int _cmbColoIndex;       
        private static int _cmbRackIndex;       
        private static int _cmbServerIndex;
        #endregion

        #region Database variables
        private static string _ServerName = "";
        private static string _ReportServerName = "";
        private static string _OpsDBName = "";
        private static string _OpsReportingDBName = "";
        #endregion

        #endregion

        #region Properties

        public static string UserNameProp
        {
            get { return Global._UserNameProp; }
            set { Global._UserNameProp = value; }
        }

        public static string ServerFieldIsVirtual
        {
            get { return Global._ServerFieldIsVirtual; }
            set { Global._ServerFieldIsVirtual = value; }
        }

        public static string ReportingDatabaseNameProp
        {
            get { return Global._ReportingDatabaseNameProp; }
            set { Global._ReportingDatabaseNameProp = value; }
        }

        public static string ScomDatabaseNameProp
        {
            get { return Global._ScomDatabaseNameProp; }
            set { Global._ScomDatabaseNameProp = value; }
        }

        public static bool ScomReportingServerAuthentication
        {
            get { return Global._scomReportingServerAuthentication; }
            set { Global._scomReportingServerAuthentication = value; }
        }

        public static string DefaultToolbar
        {
            get { return Global._DefaultToolbar; }
        }

        public static int CmbColoIndex
        {
            get { return _cmbColoIndex; }
            set { _cmbColoIndex = value; }
        }

        public static int CmbRackIndex
        {
            get { return _cmbRackIndex; }
            set { _cmbRackIndex = value; }
        }

        public static int CmbServerIndex
        {
            get { return _cmbServerIndex; }
            set { _cmbServerIndex = value; }
        }

        public static string RackServerTemplate
        {
            get { return Global._RackServerTemplate; }
            set { Global._RackServerTemplate = value; }
        }

        public static string RackServerStencil
        {
            get { return Global._RackServerStencil; }
            set { Global._RackServerStencil = value; }
        }

        public static string NA
        {
            get { return Global._NA; }
            set { Global._NA = value; }
        }

        public static string ColoDataRecordSetName
        {
            get { return _ColoDataRecordSetName; }
            set { _ColoDataRecordSetName = value; }
        }

        public static string RackDataRecordSetName
        {
            get { return _RackDataRecordSetName; }
            set { _RackDataRecordSetName = value; }
        }

        public static string ServerDataRecordSetName
        {
            get { return _ServerDataRecordSetName; }
            set { _ServerDataRecordSetName = value; }
        }

        public static string ServerFieldNetworkName
        {
            get { return _ServerFieldNetworkName; }
            set { _ServerFieldNetworkName = value; }
        }

        public static string ServerFieldPowerRating
        {
            get { return _ServerFieldPowerRating; }
            set { _ServerFieldPowerRating = value; }
        }

        public static string ServerFieldRackSpace
        {
            get { return _ServerFieldRackSpace; }
            set { _ServerFieldRackSpace = value; }
        }

        public static string ServerFieldRackName
        {
            get { return _ServerFieldRackName; }
            set { _ServerFieldRackName = value; }
        }

        public static string ServerFieldColoName
        {
            get { return _ServerFieldColoName; }
            set { _ServerFieldColoName = value; }
        }

        public static string ServerFieldIPAdress
        {
            get { return _ServerFieldIPAdress; }
            set { _ServerFieldIPAdress = value; }
        }

        public static string ServerFieldOperatingSystem
        {
            get { return _ServerFieldOperatingSystem; }
            set { _ServerFieldOperatingSystem = value; }
        }

        public static string ServerFieldCpuUsage
        {
            get { return _ServerFieldCpuUsage; }
            set { _ServerFieldCpuUsage = value; }
        }

        public static string ServerFieldTotalMem
        {
            get { return _ServerFieldTotalMem; }
            set { _ServerFieldTotalMem = value; }
        }

        public static string ServerFieldAvailMem
        {
            get { return _ServerFieldAvailMem; }
            set { _ServerFieldAvailMem = value; }
        }

        public static string ServerFieldProcessor
        {
            get { return _ServerFieldProcessor; }
            set { _ServerFieldProcessor = value; }
        }

        public static string RackFieldRackName
        {
            get { return _RackFieldRackName; }
            set { _RackFieldRackName = value; }
        }

        public static string RackFieldPowerRating
        {
            get { return _RackFieldPowerRating; }
            set { _RackFieldPowerRating = value; }
        }

        public static string RackFieldMaxUnits
        {
            get { return _RackFieldMaxUnits; }
            set { _RackFieldMaxUnits = value; }
        }

        public static string RackFieldColoName
        {
            get { return _RackFieldColoName; }
            set { _RackFieldColoName = value; }
        }

        public static string ColoFieldColoName
        {
            get { return _ColoFieldColoName; }
            set { _ColoFieldColoName = value; }
        }

        public static string ColoFieldMaxUnits
        {
            get { return _ColoFieldMaxUnits; }
            set { _ColoFieldMaxUnits = value; }
        }
        
        public static bool InternalDocOpen
        {
            get { return _internalDocOpen; }
            set { _internalDocOpen = value; }
        }

        public static DataOption DTOption
        {
            get { return _dtOption; }
            set { _dtOption = value; }
        }
        
        public static string AdoColoXml
        {
            get { return Global._adoColoXML; }
            set { Global._adoColoXML = value; }
        }

        public static string AdoRackXml
        {
            get { return Global._adoRackXML; }
            set { Global._adoRackXML = value; }
        }

        public static string AdoServerXml
        {
            get { return Global._adoServerXML; }
            set { Global._adoServerXML = value; }
        }

        public static int CpuUsageThreshold
        {
            get { return cpuUsageThreshold; }
            set { cpuUsageThreshold = value; }
        }

        public static int MaxServerConsolidate
        {
            get { return Global.maxServerConsolidate; }
            set { Global.maxServerConsolidate = value; }
        }

        //public static int CPUUsageDuration
        //{
        //    get { return Global.cpuUsageDuration; }
        //    set { Global.cpuUsageDuration = value; }
        //}

        //public static int CPUUsageDurationInHours
        //{
        //    get { return Global.cpuUsageDurationInHours; }
        //    set { Global.cpuUsageDurationInHours = value; }
        //}
        public static bool RecordSetCreated
        {
            get { return _recordSetCreated; }
            set { _recordSetCreated = value; }
        }

        public static string SheetServerSelect
        {
            get { return _sheetServerSelect; }
            set { _sheetServerSelect = value;}
        }

        public static string SheetRackSelect
        {
            get{ return _sheetRackSelect;}
            set{ _sheetRackSelect = value;}
        }

        public static string SheetColoSelect
        {
            get{ return _sheetColoSelect;}
            set{ _sheetColoSelect = value;}
        }

        public static string[] ExcelServerColumnNames
        {
            get{ return _excelServerColumnName;}
            set{ _excelServerColumnName = value;}
        }

        public static string[] ExcelRackColumnNames
        {
            get{ return _excelRackColumnName;}
            set{ _excelRackColumnName = value;}
        }

        public static string[] ExcelColoColumnNames
        {
            get{ return _excelColoColumnName;}
            set{ _excelColoColumnName = value;}
        }

        public static string[] ExcelSheetsName
        {
            get{ return _excelSheetsName;}
            set{ _excelSheetsName = value;}
        }

        public static string ExcelConnString
        {
            get{ return _excelConnString;}
            set{ _excelConnString = value;}
        }

        public static bool WindowsAuthentication
        {
            get { return _windowsAuthentication; }
            set { _windowsAuthentication = value; }
        }

        public static bool UserCredentials
        {
            get { return _userCredentials; }
            set { _userCredentials = value; }
        }

        public static string ServerSelectQuery
        {
            get { return _ServerSelectQuery; }
            set { _ServerSelectQuery = value; }
        }

        public static string RackSelectQuery
        {
            get { return _RackSelectQuery; }
            set { _RackSelectQuery = value; }
        }

        public static string ColoSelectQuery
        {
            get { return _ColoSelectQuery; }
            set { _ColoSelectQuery = value; }
        }

        public static InputDataOption IPOption
        {
            get { return _ipOption; }
            set { _ipOption = value; }
        }

        public static string ExcelFileName
        {
            get { return _excelFileName; }
            set { _excelFileName = value; }
        }

        public static Visio.Application VisioApp
        {
            get { return _visioApp; }
            set { _visioApp = value; }
        }

        public static string ServerName
        {
            get { return _ServerName; }
            set { _ServerName = value; }
        }

        public static string ReportServerName
        {
            get { return _ReportServerName; }
            set { _ReportServerName = value; }
        }

        public static string OpsDBName
        {
            get { return _OpsDBName; }
            set { _OpsDBName = value; }
        }

        public static string OpsReportingDBName
        {
            get { return _OpsReportingDBName; }
            set { _OpsReportingDBName = value; }
        }

        public static string UserName
        {
            get { return _userName; }
            set { _userName = value; }
        }

        public static string Password
        {
            get { return _password; }
            set { _password = value; }
        }

        public static string CpuUsageThresholdProp
        {
            get { return Global._CpuUsageThresholdProp; }
            set { Global._CpuUsageThresholdProp = value; }
        }

        public static string MaxServerConsolidateProp
        {
            get { return Global._MaxServerConsolidateProp; }
            set { Global._MaxServerConsolidateProp = value; }
        }

        public static string ScomServerNameProp
        {
            get { return Global._ScomServerNameProp; }
            set { Global._ScomServerNameProp = value; }
        }

        public static string ScomReportServerNameProp
        {
            get { return Global._ScomReportServerNameProp; }
            set { Global._ScomReportServerNameProp = value; }
        }

        public static string WindowsAuthenticationProp
        {
            get { return Global._WindowsAuthenticationProp; }
            set { Global._WindowsAuthenticationProp = value; }
        }

        public static string UserCredentialsProp
        {
            get { return Global._UserCredentialsProp; }
            set { Global._UserCredentialsProp = value; }
        }
                
        public static string DataOptionProp 
        {
            get { return Global._DataOptionProp; }
            set { Global._DataOptionProp = value; }
        }

        #endregion

        #region Constructor

        /// <summary>
        /// Default Constructor
        /// </summary>
        private Global()
        {
            //Left blank
        }
        #endregion

        #region Methods

        /// <summary>
        /// Get resource string from resource file
        /// </summary>
        /// <param name="resKey">Key to get the resource string</param>
        /// <returns>Resource string for the key passed</returns>
        public static string GetResourceString(string resKey)
        {
            try
            {
                return resourceMgr.GetString(resKey);
            }
            catch (Exception ex)
            {
                throw new RackException("Error in getting Resource String", ex);
            }
        }

        /// <summary>
        /// Get connection string for operation manager database
        /// </summary>
        /// <returns></returns>
        //public static string GetOpsDBConnString()
        //{
        //    string ConnString = "";

        //    if (String.IsNullOrEmpty(Global.ServerName))
        //    {
        //        return string.Empty;
        //    }

        //    if (Global.WindowsAuthentication)
        //    {
        //        ConnString = "Data Source=" + Global.ServerName + ";Initial Catalog=" + Global.OpsDBName + ";Integrated Security=SSPI";
        //    }
        //    else
        //    {
        //        ConnString = "Data Source=" + Global.ServerName + ";Initial Catalog=" + Global.OpsDBName + ";User Id=" + Global.UserName + ";Password=" + Global.Password + ";Integrated Security=SSPI";    
        //    }
        //    return ConnString;
        //}

        ///// <summary>
        ///// Get connection string for reporting server name
        ///// </summary>
        ///// <returns></returns>
        //public static string GetReportingDBConnString()
        //{
        //    string ConnString = "";

        //    if (String.IsNullOrEmpty(Global.ReportServerName) || String.IsNullOrEmpty(Global.OpsReportingDBName))
        //    {
        //        return string.Empty;
        //    }

        //    if (Global.WindowsAuthentication)
        //    {
        //        ConnString = "Data Source=" + Global.ReportServerName + ";Initial Catalog=" + Global.OpsReportingDBName + ";Integrated Security=SSPI";
        //    }
        //    else
        //    {
        //        ConnString = "Data Source=" + Global.ReportServerName + ";Initial Catalog=" + Global.OpsReportingDBName + ";User Id=" + Global.UserName + ";Password=" + Global.Password + ";Integrated Security=SSPI";
        //    }
        //    return ConnString;
        //}

        /// <summary>
        /// Get the application installed path
        /// </summary>
        /// <returns></returns>
        static public string AppPath()
        {
            string appPathFilename = System.Reflection.Assembly.GetExecutingAssembly().Location;
            string directoryName = System.IO.Path.GetDirectoryName(appPathFilename);

            if (!directoryName.EndsWith(System.IO.Path.DirectorySeparatorChar.ToString()))
            {
                directoryName += System.IO.Path.DirectorySeparatorChar.ToString();
            }

            // return result
            return directoryName;
        }

        /// <summary>
        /// Parse the string and return value part from RHS of = in the string
        /// </summary>
        /// <param name="commandString"></param>
        /// <returns></returns>
        public static string ParseCommandValue(string commandStr)
        {
            if (String.IsNullOrEmpty(commandStr))
            {
                return commandStr;
            }
            return commandStr.Substring(commandStr.IndexOf("=") + 1);
        }

        /// <summary>
        /// Get the visio objects from the context string
        /// </summary>
        /// <param name="ContextString">Context String specific to the Visio Object</param>
        /// <param name="visioApplication">Visio Appilcation for the Visio Object</param>
        /// <param name="visioDocument">Visio Document for the Visio Object</param>
        /// <param name="visioPage">Visio Page for the Visio Object</param>
        /// <param name="visioShape">Visio Shape</param>
        /// <param name="appid">Application ID for the rack Server Connector</param>
        /// <param name="cmd">Command Action specified for the Visio Object</param>
        public static void GetVisioObjects(string contextStr,
            Visio.Application visioApplication,
            ref Visio.Document visioDocument,
            ref Visio.Page visioPage,
            ref Visio.Shape visioShape,
            ref string appid,
            ref string cmd)
        {
            string _appid = null;
            string docid = null;
            string pageid = null;
            string shapeId = null;
            string shapeUId = null;
            string _cmd = null;
            bool isIndex;

            try
            {
                List<string> contextList = new List<string>();
                contextList.AddRange(contextStr.Split(' '));
                contextList.ForEach(
                    delegate(string item)
                    {
                        if (item.Contains(Global.ApplicationContextString))
                        {
                            // Get application id
                            _appid = Global.ParseCommandValue(item);
                        }
                        if (item.Contains(Global.DocumentContextString))
                        {
                            // Get document id
                            docid = Global.ParseCommandValue(item);
                        }
                        if (item.Contains(Global.PageContextString))
                        {
                            // Get page id
                            pageid = Global.ParseCommandValue(item);
                        }
                        if (item.Contains(Global.ShapeContextString))
                        {
                            // Get shape id
                            shapeId = Global.ParseCommandValue(item);
                        }
                        if (item.Contains(Global.ShapeUContextString))
                        {
                            // Get shapeU id
                            shapeUId = Global.ParseCommandValue(item);
                        }
                        if (item.Contains(Global.CommandContextString))
                        {
                            // Get command
                            _cmd = Global.ParseCommandValue(item);
                        }
                    }
                );

                isIndex = false;

                if (_appid == null)
                {
                    // Event not raised for this addin
                    return;
                }


                if (String.Compare(_appid, Global.ApplicationIndex, true, CultureInfo.CurrentCulture) == 0)
                {
                    // Check if document ID or Index is received in the ContextString
                    // Overwrite the appid to be unique after this point
                    isIndex = true;
                    _appid = Global.ApplicationId;
                }
                appid = _appid;

                if (String.Compare(appid, Global.ApplicationId, true, CultureInfo.CurrentCulture) != 0)
                {
                    return;
                }
                cmd = _cmd;

                if (shapeUId != null)
                {
                    // If shapeU id is not null use it instead of shape id
                    shapeId = shapeUId;
                }

                // get the objects based on the arguments
                if (docid != null &&
                    visioApplication.Documents.Count > 0)
                {
                    if (!isIndex)
                    {
                        // Get document reference from ID
                        visioDocument = visioApplication.Documents.get_ItemFromID(Int32.Parse(docid, System.Globalization.CultureInfo.InvariantCulture));
                    }
                    else
                    {
                        // Get document reference from Index
                        visioDocument = visioApplication.Documents[Int32.Parse(docid, System.Globalization.CultureInfo.InvariantCulture)];
                    }
                }

                if (pageid != null &&
                    visioDocument != null &&
                    visioDocument.Pages.Count > 0)
                {
                    visioPage = visioDocument.Pages[Int32.Parse(pageid, System.Globalization.CultureInfo.InvariantCulture)];
                }

                if (shapeId != null &&
                    visioPage != null &&
                    visioPage.Shapes.Count > 0)
                {
                    visioShape = visioPage.Shapes.get_ItemU(shapeId);
                }
            }
            catch (Exception ex)
            {
                // Throw user-defined exception
                throw new RackException("Get Visio Objects", ex);
            }
        }

        /// <summary>
        /// Check if the shape contains the property
        /// </summary>
        /// <param name="shape">Visio Shape</param>
        /// <param name="propertyName">Property Name</param>
        /// <returns>True if shape contains the property</returns>
        public static bool ShapePropertyExist(Visio.Shape shape, string propertyName)
        {
            if (shape == null)
            {
                return false;
            }
            return Convert.ToBoolean(shape.get_CellExists(propertyName, (short)Visio.VisExistsFlags.visExistsAnywhere));
        }      
        
        /// <summary>
        /// Configure legend table
        /// </summary>
        /// <returns></returns>
        public static Hashtable AddLegends()
        {
            Hashtable legends = new Hashtable();
            legends.Add(Global.GetResourceString("LegedNotAnalyzed"),
                        Global.GetResourceString("LegedNotAnalyzedValue"));
            legends.Add(Global.GetResourceString("LegendFailureOnAnalyze"),
                        Global.GetResourceString("LegendFailureOnAnalyzeValue"));
            legends.Add(Global.GetResourceString("LegendVirtualizable"),
                        Global.GetResourceString("LegendVirtualizableValue"));
            legends.Add(Global.GetResourceString("LegendNonVirtualizable"),
                        Global.GetResourceString("LegendNonVirtualizableValue"));
            return legends;
        }

        /// <summary>
        /// Update the Document property with the value passed.
        /// If property section does not exist it will be added.
        /// Also if property does not exist it will be added.
        /// </summary>
        /// <param name="vsoDocument">Document to update</param>
        /// <param name="propSection">Property section</param>
        /// <param name="propName">Property name</param>
        /// <param name="propValue">Property value</param>
        public static void UpdateDocumentProperty(Visio.Document vsoDocument, short propSection, string propName, string propValue)
        {
            if (vsoDocument == null)
            {
                return;
            }
            bool isUserSectionExist = Convert.ToBoolean(vsoDocument.DocumentSheet.get_SectionExists(propSection, 0));

            try
            {
                string section = string.Empty;
                switch (propSection)
                {
                    case (short)Visio.VisSectionIndices.visSectionUser:
                        section = "User.";
                        break;

                    case (short)Visio.VisSectionIndices.visSectionProp:
                        section = "Prop.";
                        break;
                }
                string sectionProp = section + propName;
                string sectionPropValue = sectionProp + ".Value";

                if (!isUserSectionExist)
                {
                    // Add user section if doesn't exist
                    vsoDocument.DocumentSheet.AddSection(propSection);
                }

                // Add property is doesnt exist
                if (!Convert.ToBoolean(vsoDocument.DocumentSheet.get_CellExistsU(
                    sectionProp,
                    (short)Visio.VisExistsFlags.visExistsAnywhere)))
                {
                    vsoDocument.DocumentSheet.AddNamedRow(
                        propSection,
                        propName,
                        (short)Visio.VisRowTags.visTagDefault);
                }

                // Update property value
                vsoDocument.DocumentSheet.get_CellsU(sectionPropValue).FormulaU = "\"" + propValue + "\"";
            }
            catch (RackException ex)
            {
                // Exception from sub function. Pass on to entry point
                throw new RackException("Update User Shape Property", ex.InnerException);
            }
            catch (Exception ex)
            {
                // Exception from current function
                throw new RackException("Update User Shape Property", ex);
            }
        }
        /// <summary>
        /// Get value of a Document property
        /// </summary>
        /// <param name="vsoDocument">Visio Document</param>
        /// <param name="sectionProp">Property name</param>
        /// <returns>Property value</returns>
        public static string GetDocumentProperty(Visio.Document vsoDocument, string sectionProp)
        {
            string propValue = string.Empty;

            if (vsoDocument == null)
                return propValue;

            try
            {
                string sectionPropValue = sectionProp + ".Value";

                // Get property value if exist
                if (Convert.ToBoolean(vsoDocument.DocumentSheet.get_CellExistsU(
                    sectionProp,
                    (short)Visio.VisExistsFlags.visExistsAnywhere)))
                {
                    propValue = vsoDocument.DocumentSheet.get_CellsU(sectionPropValue).FormulaU.Trim('\"');
                }

                return propValue;
            }
            catch (RackException ex)
            {
                // Exception from sub function. Pass on to entry point
                throw new RackException("Get Document Property", ex.InnerException);
            }
            catch (Exception ex)
            {
                // Exception from current function
                throw new RackException("Get Document Property", ex);
            }
        }
        #endregion
    }
}
